package decaf.frontend;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import decaf.Location;
import decaf.tree.Tree;
import decaf.tree.Tree.ClassDef;
import decaf.tree.Tree.Expr;
import decaf.tree.Tree.LValue;
import decaf.tree.Tree.MethodDef;
import decaf.tree.Tree.TopLevel;
import decaf.tree.Tree.TypeLiteral;
import decaf.tree.Tree.VarDef;
import decaf.tree.Tree.IfSub;
import decaf.utils.MiscUtils;

public class SemValue {
	
	public IfSub ifSub;
	
	public List<IfSub> ifList;
	
    public int code;

    public int counter;

    public Vector<Integer> svec;

    public Location loc;

    public Vector<Location> lvec;

    public int typeTag;

    public Object literal;

    public String ident;

    public List<ClassDef> clist;

    /**
     * field list
     */
    public List<Tree> flist;

    public List<VarDef> vlist;

    /**
     * statement list
     */
    public List<Tree> slist = new ArrayList<Tree>();

    public List<Expr> elist;

    public TopLevel prog;

    public ClassDef cdef;

    public VarDef vdef;

    public MethodDef fdef;

    public TypeLiteral type;

    public Tree stmt;

    public Expr expr;

    public Expr expr1;

    public Vector<Expr> evec;

    public LValue lvalue;

    public Vector<SemValue> vec;

    /**
     * 创建一个关键字的语义值
     *
     * @param code 关键字的代表码
     * @return 对应关键字的语义值
     */
    public static SemValue createKeyword(int code) {
        SemValue v = new SemValue();
        v.code = code;
        return v;
    }

    /**
     * 创建一个操作符的语义值
     *
     * @param code 操作符的代表码
     * @return 对应操作符的语义值
     */
    public static SemValue createOperator(int code) {
        SemValue v = new SemValue();
        v.code = code;
        return v;
    }

    /**
     * 创建一个常量的语义值
     *
     * @param value 常量的值
     * @return 对应的语义值
     */
    public static SemValue createLiteral(int tag, Object value) {
        SemValue v = new SemValue();
        v.code = Parser.LITERAL;
        v.typeTag = tag;
        v.literal = value;
        return v;
    }

    /**
     * 创建一个标识符的语义值
     *
     * @param name 标识符的名字
     * @return 对应的语义值（标识符名字存放在sval域）
     */
    public static SemValue createIdentifier(String name) {
        SemValue v = new SemValue();
        v.code = Parser.IDENTIFIER;
        v.ident = name;
        return v;
    }

    /**
     * 获取这个语义值的字符串表示<br>
     * <p>
     * 我们建议你在构造词法分析器之前先阅读一下这个函数。
     */
    public String toString() {
        String msg;
        switch (code) {
            // 关键字
            case Parser.BOOL:
                msg = "keyword  : bool";
                break;
            case Parser.BREAK:
                msg = "keyword  : break";
                break;
            case Parser.CLASS:
                msg = "keyword  : class";
                break;
            case Parser.ELSE:
                msg = "keyword  : else";
                break;
            case Parser.EXTENDS:
                msg = "keyword  : extends";
                break;
            case Parser.FOR:
                msg = "keyword  : for";
                break;
            case Parser.IF:
                msg = "keyword  : if";
                break;
            case Parser.INT:
                msg = "keyword  : int";
                break;
            case Parser.INSTANCEOF:
                msg = "keyword  : instanceof";
                break;
            case Parser.NEW:
                msg = "keyword  : new";
                break;
            case Parser.NULL:
                msg = "keyword  : null";
                break;
            case Parser.PRINT:
                msg = "keyword  : Print";
                break;
            case Parser.READ_INTEGER:
                msg = "keyword  : ReadInteger";
                break;
            case Parser.READ_LINE:
                msg = "keyword  : ReadLine";
                break;
            case Parser.RETURN:
                msg = "keyword  : return";
                break;
            case Parser.STRING:
                msg = "keyword  : string";
                break;
            case Parser.THIS:
                msg = "keyword  : this";
                break;
            case Parser.VOID:
                msg = "keyword  : void";
                break;
            case Parser.WHILE:
                msg = "keyword  : while";
                break;
            case Parser.STATIC:
                msg = "keyword : static";
                break;

            // 常量
            case Parser.LITERAL:
                switch (typeTag) {
                    case Tree.INT:
                    case Tree.BOOL:
                        msg = "constant : " + literal;
                        break;
                    default:
                        msg = "constant : " + MiscUtils.quote((String) literal);
                }
                break;

            // 标识符
            case Parser.IDENTIFIER:
                msg = "identifier: " + ident;
                break;

            // 操作符
            case Parser.AND:
                msg = "operator : &&";
                break;
            case Parser.EQUAL:
                msg = "operator : ==";
                break;
            case Parser.GREATER_EQUAL:
                msg = "operator : >=";
                break;
            case Parser.LESS_EQUAL:
                msg = "operator : <=";
                break;
            case Parser.NOT_EQUAL:
                msg = "operator : !=";
                break;
            case Parser.OR:
                msg = "operator : ||";
                break;
            default:
                msg = "operator : " + (char) code;
                break;
        }
        return (String.format("%-15s%s", loc, msg));
    }
}
